#include "SingletonThreadPool.h"
#include <iostream>

ThreadPool::ThreadPool()
{
    for (size_t i = 0; i < std::thread::hardware_concurrency(); ++i)
    {
        m_threads.emplace_back(new std::thread(std::bind(&ThreadPool::run, this)));
        m_threads[i]->detach();
    }
}

// void ThreadPool::run()
// {
//     try
//     {
//         std::function<void()> task;
//         while (true)
//         {
//             {
//                 std::unique_lock<std::mutex> lock(m_mutex);
//                 while (m_tasks.empty())
//                 {
//                     if (m_stop)
//                     {
//                         return;
//                     }
//                     m_cond.wait(lock);
//                 }

//                 task = m_tasks.front();
//                 m_tasks.pop();
//             }
//             if (task != nullptr)
//             {
//                 task();
//             }
//         }
//     } catch(const std::exception& e) {
//         std::cout << "exeception throw!" << std::endl;
//         std::cout << e.what() << std::endl;
//     }
// }

void ThreadPool::run()
{
    std::function<void()> task;
    while (true)
    {
        {
            std::unique_lock<std::mutex> lock(m_mutex);
            while (m_tasks.empty() && !m_stop)
            {
                m_cond.wait(lock);
            }

            if (m_stop)
            {
                //TODO 剩下的任务都由一个线程处理，可以优化
                while (!m_tasks.empty())
                {
                    task = m_tasks.front();
                    m_tasks.pop();
                    if(task != nullptr) {
                        task();
                    }
                }
                return;
            }
            task = m_tasks.front();
            m_tasks.pop();
        }
        if (task != nullptr)
        {
            task();
            task = nullptr;
        }
    }
}

void ThreadPool::append(Task task)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_tasks.push(task);
    m_cond.notify_one();
}

void ThreadPool::stop()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_stop = true;
    m_cond.notify_all();
}